#ifndef MESSAGES_H_
#define MESSAGES_H_

#include "../Game Objects/CBaseObject.h"

#include <vector>
using namespace std;

enum EMessageType { MSG_NULL, MSG_BASE, MSG_CREATE_MONEYBAG, MSG_CREATE_ROCK, MSG_CREATE_RANGED, MSG_CREATE_MELEE, MSG_CREATE_EXPLODING, MSG_CREATE_PROJECTILE, MSG_CREATE_EMITTER, MSG_DESTROY_OBJECT };

class CBaseMessage
{
	EMessageType messageType;

public:
	CBaseMessage(EMessageType messageType)
	{
		this->messageType = messageType;
	}

	virtual ~CBaseMessage(void) {}

	EMessageType GetMessageType(void) { return messageType; }
};

class CCreateRangedEnemyMessage : public CBaseMessage
{
	int currentWave;
	int type;
	float posX;
	float posY;

public:
	CCreateRangedEnemyMessage(float posX, float posY, int type, int currentWave) : CBaseMessage(MSG_CREATE_RANGED)
	{
		this->posX = posX;
		this->posY = posY;
		this->type = type;
		this->currentWave = currentWave;
	}

	~CCreateRangedEnemyMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	int GetType(void)	{return type;}
	int GetCurrWave(void)	{return currentWave;}
};

class CCreateMeleeEnemyMessage : public CBaseMessage
{
	int currentWave;
	int type;
	float posX;
	float posY;

public:
	CCreateMeleeEnemyMessage(float posX, float posY, int type, int currentWave) : CBaseMessage(MSG_CREATE_MELEE)
	{
		this->posX = posX;
		this->posY = posY;
		this->type = type;
		this->currentWave = currentWave;
	}

	~CCreateMeleeEnemyMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	int GetType(void)	{return type;}
	int GetCurrWave(void)	{return currentWave;}
};

class CCreateExplodingEnemyMessage : public CBaseMessage
{
	int currentWave;
	float posX;
	float posY;

public:
	CCreateExplodingEnemyMessage(float posX, float posY, int currentWave) : CBaseMessage(MSG_CREATE_EXPLODING)
	{
		this->posX = posX;
		this->posY = posY;
		this->currentWave = currentWave;
	}

	~CCreateExplodingEnemyMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	int GetCurrWave(void)	{return currentWave;}
};

class CCreateMoneyBagMessage : public CBaseMessage
{
	int currentWave;
	float posX;
	float posY;
	float velX;
	float velY;

public:
	CCreateMoneyBagMessage(float posX, float posY, float velX, float velY, int currentWave) : CBaseMessage(MSG_CREATE_MONEYBAG)
	{
		this->posX = posX;
		this->posY = posY;
		this->velX = velX;
		this->velY = velY;
		this->currentWave = currentWave;
	}

	~CCreateMoneyBagMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	float GetVelX(void)	{return velX;}
	float GetVelY(void)	{return velY;}
	int GetCurrWave(void)	{return currentWave;}
};


class CCreateRockMessage : public CBaseMessage
{
	int currentLvl;
	float posX;
	float posY;

public:
	CCreateRockMessage(float posX, float posY, int currentLvl) : CBaseMessage(MSG_CREATE_ROCK)
	{
		this->posX = posX;
		this->posY = posY;
		this->currentLvl = currentLvl;
	}

	~CCreateRockMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	int GetCurrLvl(void)	{return currentLvl;}
};

class CCreateProjectileMessage : public CBaseMessage
{
	float posX;
	float posY;
	float velX;
	float velY;

	int type;

public:
	CCreateProjectileMessage(float posX, float posY, float velX, float velY, int type) : CBaseMessage(MSG_CREATE_PROJECTILE)
	{
		this->posX = posX;
		this->posY = posY;
		this->velX = velX;
		this->velY = velY;
		this->type = type;
	}

	~CCreateProjectileMessage(void) {}

	float GetPosX(void)	{return posX;}
	float GetPosY(void)	{return posY;}
	float GetVelX(void)	{return velX;}
	float GetVelY(void)	{return velY;}
	int GetType(void)	{return type;}
};

class CDestroyObjectMessage : public CBaseMessage
{
	CBaseObject* object;

	int type;

public:
	CDestroyObjectMessage(CBaseObject* object, int type) : CBaseMessage(MSG_DESTROY_OBJECT)
	{
		this->type = type;
		this->object = object;
		object->AddRef();
	}

	~CDestroyObjectMessage(void)
	{
		object->Release();
	}

	int GetType()					{ return type; }
	void SetType(int objectType)	{type = objectType;}

	CBaseObject* GetObject(void) { return object; }
};

class CCreateParticleEmitterMessage : public CBaseMessage
{
	float positionX;
	float positionY;
	float velocityX;
	float velocityY;
	int Type;

public:
	CCreateParticleEmitterMessage(float positionX, float positionY, float velocityX, float velocityY, int nType) : CBaseMessage(MSG_CREATE_EMITTER)
	{
		this->positionX = positionX;
		this->positionY = positionY;
		this->velocityX = velocityX;
		this->velocityY = velocityY;
		this->Type = nType;
	}

	~CCreateParticleEmitterMessage(void) {}

	float GetPositionX(void)	{return positionX;}
	float GetPositionY(void)	{return positionY;}
	float GetVelocityX(void)	{return velocityX;}
	float GetVelocityY(void)	{return velocityY;}
	int GetType(void)			{return Type;}
};

#endif